package com.fwtai.service.web;

import com.fwtai.bean.PageFormData;
import com.fwtai.config.ConfigFile;
import com.fwtai.config.LocalUserId;
import com.fwtai.tool.ToolClient;
import com.fwtai.tool.ToolString;
import com.fwtai.web.ProxyDao;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 代理统计
 * @作者 田应平
 * @版本 v1.0
 * @QQ号码 444141300
 * @创建日期 2022-06-21 11:02:27
 * @官网 <url>http://www.fwtai.com</url>
*/
@Service
public class ProxyService{

  private final ProxyDao proxyDao;

  private final BCryptPasswordEncoder passworder;

  private final ThreadPoolTaskExecutor taskExecutor;

  public ProxyService(final ProxyDao proxyDao,final BCryptPasswordEncoder passworder,final ThreadPoolTaskExecutor taskExecutor){
    this.proxyDao = proxyDao;
    this.passworder = passworder;
    this.taskExecutor = taskExecutor;
  }

  public String getProxyTree(final Long pid,final Integer level){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      final long loginKey = Long.parseLong(loginId);
      final boolean is_super = ConfigFile.manager(loginKey);
      if(is_super){//管理员查看
        final HashMap<String,Object> map = new HashMap<>(2);
        map.put("pid",pid);
        map.put("level",level);
        return getTree(map,level,is_super);
      }
      final HashMap<String,Object> proxyType = proxyDao.getProxyType(loginKey);
      if(proxyType == null){
        return ToolClient.createJsonFail("暂无权限查看");
      }else{
        return getProxyTree(level,proxyType,pid,loginKey);
      }
    },taskExecutor).join();
  }

  //代理查看树形列表
  private String getProxyTree(final Integer level,final HashMap<String,Object> proxyType,final Long pid,final Long loginKey){
    final Integer type = (Integer) proxyType.get("type");
    if(level != null && level > 2){
      return ToolClient.createJsonFail("最多仅能查询到区代");
    }
    final HashMap<String,Object> map = new HashMap<>(6);
    switch (type){//代理类型
      case 1://省级分公司
        map.put("pid",getPid(level,type,proxyType,pid));
        if(level == null){//为空时说明是首次加载,否则是点击节点加载数据
          map.put("level",1);
        }else{
          map.put("level",level);
          map.put("county_id",proxyType.get("county_id"));
        }
        return ToolClient.queryJson(proxyDao.getProxyTree(map));
      case 2://市级分公司
        map.put("pid",getPid(level,type,proxyType,pid));
        if(level == null){
          map.put("level",2);
        }
        return ToolClient.queryJson(proxyDao.getProxyTree(map));
      case 3://区县级代理,仅显示门店,即仅显示右边的下部分
        final HashMap<String,Object> attach = new HashMap<>(2);
        attach.put("grade",3);
        attach.put("list",proxyDao.get_proxy_store(loginKey));//仅查询区级代理的直属直营门店
        return ToolClient.json198(attach);
      default:
        return ToolClient.createJsonFail("暂无权限查看");
    }
  }

  //区分是否首次加载数据,level为空时是首次加载数据
  private Long getPid(final Integer level,final Integer type,final HashMap<String,Object> proxyType,final Long pid){
    switch (type){
      case 1://省级分公司
        if(level == null){
          return (Long) proxyType.get("province_id");
        }
        return pid;
      case 2://市级分公司
        if(level == null){
          return (Long) proxyType.get("city_id");
        }
        return pid;
      case 3://区县级代理,区代时仅显示门店即可
        if(level == null){
          return (Long) proxyType.get("county_id");
        }
        return pid;
      default:
        break;
    }
    return pid;
  }

  private void addAttachData(final List<Map<String,Object>> list){
    final Map<String,Object> objectMap = new HashMap<>(4);
    objectMap.put("kid","888888888888888888");
    objectMap.put("name","中国大陆");
    objectMap.put("grade","-1");
    objectMap.put("isParent","false");
    list.add(0,objectMap);
  }

  //管理员查看树形列表
  private String getTree(final HashMap<String,Object> map,final Integer level,final boolean is_super){
    if(level != null && level > 2){
      return ToolClient.createJsonFail("最多仅能查询到区代");
    }
    final List<Map<String,Object>> list = proxyDao.getProxyTree(map);
    if(level == null && is_super){//首次加载且是管理员时附加‘中国大陆’
      addAttachData(list);
    }
    return ToolClient.queryJson(list);
  }

  public String listData(final PageFormData formData){
    final String loginId = LocalUserId.get();
    return CompletableFuture.supplyAsync(()->{
      try{
        if(ToolClient.dataTableMysql(formData) == null) return ToolClient.jsonValidateField();
        final String p_grade = "query_grade";
        final String p_kid = "query_kid";
        final Integer grade = formData.getInteger(p_grade);
        final long kid = formData.getLong(p_kid);
        if(grade == -1){//中国大陆
          formData.remove(p_grade);
          formData.remove(p_kid);
        }
        switch (grade){// 根据区域及区域的level阶层选择
          case 1:
            formData.put("province_id",kid);
            break;
          case 2:
            formData.put("city_id",kid);
            break;
          case 3:
          case 4://此处是便于没有区县的地级市查询门店
            formData.put("county_id",kid);
            break;
          default:
            break;
        }
        final List<HashMap<String,Object>> listData = proxyDao.getListData(formData);
        final HashMap<String,Object> map = (!listData.isEmpty()) ? listData.get(0) : null;
        final Long userId = map != null ? (Long)map.get("user_id") : null;
        final CompletableFuture<Integer> listTotal = CompletableFuture.supplyAsync(() -> proxyDao.getListTotal(formData),taskExecutor);
        final long loginKey = Long.parseLong(loginId);
        final boolean is_super = ConfigFile.manager(loginKey);
        final HashMap<String,Object> attach = new HashMap<>(2);
        if(is_super){//管理员查看
          if(grade != -1){
            attach.put("grade",grade);
          }
          switch (grade){
            case 1://查询市代
              attach.put("list",proxyDao.getProxyCity(kid));
              break;
            case 2://查询区代
              attach.put("list",proxyDao.getProxyCounty(kid));
              break;
            case 3://查询直营门店
              if(userId != null){
                attach.put("list",proxyDao.getProxyStore(userId));
              }
              break;
            case 4://此处是便于没有区县的地级市查询门店
              if(userId != null){
                attach.put("list",proxyDao.getProxyStore(userId));
              }
              break;
          }
        }else{
          final HashMap<String,Object> proxyType = proxyDao.getProxyType(loginKey);
          if(proxyType == null){
            return ToolClient.createJsonFail("暂无权限查看");
          }
          final Integer type = (Integer) proxyType.get("type");//代理类型,1省代;2市代;3区县代理
          //当是省代时，点击市级是，①上部分显示的市代，下部分没有;②点击区代时上面是区代，下部分是直营门店;
          // 当是区代时仅显示下部分
          if(type == 3){
            attach.put("grade",3);
            if(userId != null){
              attach.put("list",proxyDao.getProxyStore(userId));
            }
          }else{
            if(grade == 4){//此处是便于没有区县的地级市查询门店
              attach.put("grade",3);
            }else{
              attach.put("grade",grade);
            }
            switch (grade){//前端传递在阶级数
              case 2://查询区代
                attach.put("list",proxyDao.getProxyCounty(kid));
                break;
              case 3://查询直营门店
                if(userId != null){
                  attach.put("list",proxyDao.getProxyStore(userId));
                }
                break;
            }
          }
        }
        return ToolClient.dataTableOK(listData,listTotal.join(),(attach.size() > 0) ? attach : null);
      } catch (final Exception ignored){
        return ToolClient.dataTableException();
      }
    },taskExecutor).join();
  }

  public String editUser(final Long userId,final String user_password,final String verify_password){
    return CompletableFuture.supplyAsync(()->{
      if(userId == null){
        return ToolClient.jsonValidateField();
      }
      final Long exist = proxyDao.queryExistById(userId);
      if(exist == null){
        return ToolClient.createJsonFail("用户已不存在,刷新重试");
      }
      if(!user_password.equals(verify_password)){
        return ToolClient.createJsonFail("输入的两次密码不一致");
      }
      final HashMap<String,Object> map = new HashMap<>(2);
      map.put("userId",userId);
      map.put("password",passworder.encode(user_password));
      return ToolClient.executeRows(proxyDao.editUser(map));
    },taskExecutor).join();
  }

  public String getViewOrder(final PageFormData formData){
    return CompletableFuture.supplyAsync(()->{
      try{
        if(ToolClient.dataTableMysql(formData,"userId") == null) return ToolClient.jsonValidateField();
        final CompletableFuture<List<HashMap<String,Object>>> listData = CompletableFuture.supplyAsync(() -> proxyDao.getViewOrderData(formData),taskExecutor);
        final List<HashMap<String,Object>> list = listData.join();
        list.forEach(map -> {
          map.put("buyer", ToolString.replacePhone((String) map.get("buyer")));//处理数据脱敏
          map.put("payee", ToolString.replacePhone((String) map.get("payee")));//处理数据脱敏
        });
        final CompletableFuture<Integer> listTotal = CompletableFuture.supplyAsync(() -> proxyDao.getViewOrderTotal(formData),taskExecutor);
        return ToolClient.dataTableOK(listData.join(),listTotal.join());
      } catch (final Exception ignored){
        return ToolClient.dataTableException();
      }
    },taskExecutor).join();
  }

  public String getViewOrderInfo(final Long out_trade_no){
    return CompletableFuture.supplyAsync(()->{
      if(out_trade_no == null){
        return ToolClient.jsonValidateField();
      }
      final Integer payType = proxyDao.queryOrderPayType(out_trade_no);
      if(payType == null){
        return ToolClient.createJsonFail("数据不存在,刷新重试");
      }
      final HashMap<String,Object> map = proxyDao.queryOrder(out_trade_no,payType);
      final List<HashMap<String,Object>> list = proxyDao.getOrderDetails((Long) map.get("kid"),payType);
      final HashMap<String,Object> result = new HashMap<>(2);
      result.put("goodsOrder",map);
      if(list != null){
        result.put("orderDetails",list);
      }
      return ToolClient.queryJson(result);
    },taskExecutor).join();
  }
}